home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / sysstat / RCS / sysstat.c,v < prev    next >
Encoding:
Text File  |  1992-06-02  |  24.3 KB  |  963 lines

  1. head     1.8;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.8
  10. date     92.06.02.13.21.38;  author kupfer;  state Exp;
  11. branches ;
  12. next     1.7;
  13.  
  14. 1.7
  15. date     90.02.16.11.44.58;  author jhh;  state Exp;
  16. branches ;
  17. next     1.6;
  18.  
  19. 1.6
  20. date     89.10.18.22.40.23;  author jhh;  state Exp;
  21. branches ;
  22. next     1.5;
  23.  
  24. 1.5
  25. date     89.08.30.09.19.03;  author brent;  state Exp;
  26. branches ;
  27. next     1.4;
  28.  
  29. 1.4
  30. date     89.08.29.15.58.03;  author jhh;  state Exp;
  31. branches ;
  32. next     1.3;
  33.  
  34. 1.3
  35. date     89.08.03.16.05.30;  author brent;  state Exp;
  36. branches ;
  37. next     1.2;
  38.  
  39. 1.2
  40. date     88.12.22.11.07.44;  author douglis;  state Exp;
  41. branches ;
  42. next     1.1;
  43.  
  44. 1.1
  45. date     88.10.31.13.57.46;  author douglis;  state Exp;
  46. branches ;
  47. next     ;
  48.  
  49.  
  50. desc
  51. @program to print system status and statistics.  This is the version
  52. prior to any conversions to the new library.
  53. @
  54.  
  55.  
  56. 1.8
  57. log
  58. @Add -t and -p options.  Tweaks & lint.
  59. @
  60. text
  61. @/*
  62.  * sysStat.c --
  63.  *
  64.  *    Statistics generation for system calls, and a hook for other
  65.  *    system-related commands.
  66.  *
  67.  * Copyright 1986, 1988 Regents of the University of California
  68.  * Permission to use, copy, modify, and distribute this
  69.  * software and its documentation for any purpose and without
  70.  * fee is hereby granted, provided that the above copyright
  71.  * notice appear in all copies.  The University of California
  72.  * makes no representations about the suitability of this
  73.  * software for any purpose.  It is provided "as is" without
  74.  * express or implied warranty.
  75.  */
  76.  
  77. #ifndef lint
  78. static char rcsid[] = "$Header: /sprite/src/cmds/sysstat/RCS/sysstat.c,v 1.7 90/02/16 11:44:58 jhh Exp Locker: kupfer $ SPRITE (Berkeley)";
  79. #endif not lint
  80.  
  81. #include <sprite.h>
  82. #include <spriteTime.h>
  83. #include <fs.h>
  84. #include <sysStats.h>
  85. #include <status.h>
  86. #include <stdio.h>
  87. #include <stdlib.h>
  88. #include <option.h>
  89. #include <host.h>
  90. #include <kernel/sysSysCall.h>
  91. #include <kernel/trace.h>
  92. #include <kernel/sync.h>
  93. #include <kernel/sched.h>
  94. #include <kernel/mach.h>
  95.  
  96. #include "syscalls.h"
  97.  
  98. /*
  99.  * Variables for options.
  100.  */
  101.  
  102. int countCalls = 0;
  103. #define JUST_CALLS    1
  104. #define CALLS_AND_TIMES    2
  105.  
  106. int resetCount = 0;
  107. int printVersion = 0;
  108. int doSyncStat = 0;
  109. int doSchedStat = 0;
  110. int enableProfiling = -1;
  111.  
  112. Option optionArray[] = {
  113.     {OPT_CONSTANT(JUST_CALLS), "c", (Address)&countCalls,
  114.      "Print the number of system calls invoked."},
  115.     {OPT_TRUE, "l", (Address)&doSyncStat, "Print lock (Sync) statistics"},
  116.     {OPT_INT, "p", (Address)&enableProfiling,
  117.      "Set or clear the flag that controls system call profiling"},
  118.     {OPT_TRUE, "R", (Address)&resetCount,
  119.      "Reset the count of system calls to 0."},
  120.     {OPT_CONSTANT(CALLS_AND_TIMES), "t", (Address)&countCalls,
  121.      "Print the number of system calls invoked and the time they took."},
  122.     {OPT_TRUE, "v", (Address)&printVersion,
  123.      "Print compilation timestamp for the kernel (DEFAULT)."},
  124.     {OPT_TRUE, "x", (Address)&doSchedStat, "Print scheduling statistics"},
  125. };
  126.  
  127. /*
  128.  * Constants used by tracing routines:
  129.  *     PROC_NUM_EVENTS - the number of valid trace events for proc.\
  130.  */
  131.  
  132. #define PROC_NUM_EVENTS 5
  133.  
  134.  
  135. /*
  136.  *----------------------------------------------------------------------
  137.  *
  138.  * main --
  139.  *
  140.  *    Driver.
  141.  *
  142.  * Results:
  143.  *    None.
  144.  *
  145.  * Side effects:
  146.  *    Variable.
  147.  *
  148.  *----------------------------------------------------------------------
  149.  */
  150.  
  151.  
  152. main(argc, argv)
  153.     int argc;
  154.     char *argv[];
  155. {
  156.     ReturnStatus status = SUCCESS;
  157.     char          version[128];
  158.     Sys_MachineInfo    machineInfo;
  159.     int            numProcessors;
  160.     int exitStatus = 0;
  161.  
  162.     (void) Opt_Parse(argc, argv, optionArray, Opt_Number(optionArray),
  163.              OPT_ALLOW_CLUSTERING);
  164.     if (! (printVersion || countCalls || resetCount)) {
  165.     printVersion = 1;
  166.     }
  167.     if (printVersion) {
  168.     if (Sys_Stats(SYS_GET_VERSION_STRING, sizeof(version), version) ==
  169.         SUCCESS) {
  170.         int virtualHost, physicalHost;
  171.         Host_Entry *hostPtr;
  172.  
  173.         if ((Proc_GetHostIDs(&virtualHost, &physicalHost) != SUCCESS) ||
  174.         ((hostPtr = Host_ByID(physicalHost)) == (Host_Entry *)NULL)) {
  175.         (void) printf("%s\n", version);
  176.         } else {
  177.         char *cPtr;
  178.         /*
  179.          * Nuke domain suffix and print hostname with kernel version.
  180.          */
  181.         for (cPtr = hostPtr->name ; *cPtr ; cPtr++) {
  182.             if (*cPtr == '.') {
  183.             *cPtr = '\0';
  184.             break;
  185.             }
  186.         }
  187.         (void) printf("%-20s %s\n", hostPtr->name, version);
  188.         }
  189.         (void) fflush(stdout);
  190.     }
  191.     }
  192.  
  193.     if (countCalls) {
  194.     status = PrintNumCalls(countCalls);
  195.     }
  196.     if (status != SUCCESS) {
  197.     fprintf(stderr, "Couldn't get stats about Sprite calls: %s\n",
  198.         Stat_GetMsg(status));
  199.     exitStatus = 1;
  200.     }
  201.  
  202.     if (resetCount) {
  203.     status = Sys_Stats(SYS_SYS_CALL_STATS, 0, (Address) NULL);
  204.     }
  205.     if (status != SUCCESS) {
  206.     fprintf(stderr, "Couldn't reset stats about Sprite calls: %s\n",
  207.         Stat_GetMsg(status));
  208.     exitStatus = 1;
  209.     }
  210.  
  211.     if (enableProfiling != -1) {
  212.     status = Sys_Stats(SYS_SYS_CALL_STATS_ENABLE, enableProfiling,
  213.                (Address)NULL);
  214.     }
  215.     if (status != SUCCESS) {
  216.     fprintf(stderr, "Couldn't %s profiling for Sprite calls: %s\n",
  217.         (enableProfiling ? "enable" : "disable"),
  218.         Stat_GetMsg(status));
  219.     exitStatus = 1;
  220.     }
  221.  
  222.     status = Sys_GetMachineInfo(sizeof(Sys_MachineInfo), &machineInfo);
  223.     if (status != SUCCESS) {
  224.     printf("Sys_GetMachineInfo failed: %s.\n", Stat_GetMsg(status));
  225.     exit(1);
  226.     }
  227.     numProcessors = machineInfo.processors;
  228.     if (doSyncStat) {
  229.     PrintSyncStats(numProcessors);
  230.     }
  231.     if (doSchedStat) {
  232.     PrintSchedStats(numProcessors);
  233.     }
  234.  
  235.     exit(exitStatus);
  236. }
  237.  
  238.  
  239. /*
  240.  *----------------------------------------------------------------------
  241.  *
  242.  * PrintNumCalls --
  243.  *
  244.  *    Print the number of system calls invoked by processes since the last
  245.  *    time the counter was reset.
  246.  *
  247.  * Results:
  248.  *    The return status from Sys_Stats is returned.
  249.  *
  250.  * Side effects:
  251.  *    The number of calls is output.
  252.  *
  253.  *----------------------------------------------------------------------
  254.  */
  255.  
  256. ReturnStatus
  257. PrintNumCalls(callType)
  258.     int callType;        /* just calls, or times too */
  259. {
  260.     Address buffer;    /* Buffer to hold counters */
  261.     int bufSize;
  262.     ReturnStatus status;
  263.     int i;
  264.     int numForeign = 0;
  265.     int numLocal = 0;
  266.     register int *numCalls;    /* array of counts (one per call) */
  267.     Time *totalTimes;        /* array of times (one per call) */
  268.     int msec;
  269.     int numAlloc;        /* number of entries to allocate space for */
  270.  
  271.     /*
  272.      * Allocate an array to hold the numbers from the kernel.  This will 
  273.      * either be an array of counters or an array of counters followed by 
  274.      * an array of Time values.
  275.      */
  276.     numAlloc = sysCallArraySize / sizeof(SysCallInfo);
  277.     bufSize = numAlloc * (callType == JUST_CALLS
  278.               ? sizeof(int)
  279.               : sizeof(int) + sizeof(Time));
  280.     buffer = malloc((unsigned) bufSize);
  281.  
  282.     /* 
  283.      * Now get the numbers from the kernel.
  284.      */
  285.     status = Sys_Stats((callType == JUST_CALLS
  286.             ? SYS_SYS_CALL_STATS
  287.             : SYS_SYS_CALL_TIMES),
  288.                numAlloc, buffer);
  289.     if (status != SUCCESS) {
  290.     fprintf(stderr, "Couldn't get %s: %s\n",
  291.         (callType == JUST_CALLS ? "counters" : "counters and times"),
  292.          Stat_GetMsg(status));
  293.     return(status);
  294.     }
  295.  
  296.     /* 
  297.      * Print out the results.  The format depends on whether we give the 
  298.      * time as well as the count.
  299.      */
  300.     numCalls = (int *) buffer;
  301.     totalTimes = (Time *)((int *)buffer + numAlloc);
  302.  
  303.     for (i = 0; i < numAlloc; i++) {
  304.     if (callType == JUST_CALLS) {
  305.         (void) printf("%d\t%-30s", numCalls[i], sysCallArray[i].name);
  306.         if (sysCallArray[i].local) {
  307.         numLocal += numCalls[i];
  308.         (void) printf("local\n");
  309.         } else {
  310.         numForeign += numCalls[i];
  311.         (void) printf("remote\n");
  312.         }
  313.     } else {
  314.         (void)printf("%d\t%d.%03d\t", numCalls[i], 
  315.              totalTimes[i].seconds,
  316.              (totalTimes[i].microseconds + 500) / 1000);
  317.         if (numCalls[i] != 0) {
  318.         Time_Divide(totalTimes[i], numCalls[i],
  319.                 &totalTimes[i]);
  320.         }
  321.         msec = (int)Time_ToMs(totalTimes[i]);
  322.         if (msec < 10 && !Time_EQ(totalTimes[i], time_ZeroSeconds)) {
  323.         (void)printf("(%d.%03d ms avg)\t",
  324.                  msec, totalTimes[i].microseconds % 1000);
  325.         } else {
  326.         (void)printf("(%d ms avg)\t",
  327.                  (int)(Time_ToMs(totalTimes[i]) + 0.5));
  328.         }
  329.         (void)printf("%-30s\n", sysCallArray[i].name);
  330.     }
  331.     }
  332.     if (callType == JUST_CALLS) {
  333.     (void) printf("\n\nTotal number of calls: %d local, %d remote.\n",
  334.               numLocal, numForeign);
  335.     (void) printf("%d/%d = %6.2f%% remote.\n",
  336.               numForeign, numForeign + numLocal, 
  337.               ((double) numForeign) / (numForeign + numLocal) * 100.);
  338.     }
  339.     return(0);
  340. }
  341.  
  342. PrintSyncStats(numProcessors)
  343.     int    numProcessors;    
  344. {
  345.     Sync_Instrument    syncStat[MACH_MAX_NUM_PROCESSORS];
  346.     ReturnStatus    status;
  347.     int            i;
  348.  
  349.     status = Sys_Stats(SYS_SYNC_STATS, sizeof(syncStat), syncStat);
  350.     if (status != SUCCESS) {
  351.     return;
  352.     }
  353.     printf("Sync Statistics\n");
  354.     for (i = 0; i < numProcessors; i++) {
  355.     printf("Processor %d\n", i);
  356.     printf("numWakeups = %d\n", syncStat[i].numWakeups);
  357.     printf("numWakeupCalls = %d\n", syncStat[i].numWakeupCalls);
  358.     printf("numSpuriousWakeups = %d\n", syncStat[i].numSpuriousWakeups);
  359.     printf("numLocks = %d\n", syncStat[i].numLocks);
  360.     printf("numUnlocks = %d\n", syncStat[i].numUnlocks);
  361.     printf("Misses on sched_Mutex in idle loop = %d\n",
  362.             syncStat[i].sched_MutexMiss);
  363.     }
  364. }
  365.  
  366. PrintSchedStats(numProcessors)
  367.     int numProcessors;
  368. {
  369.     Sched_Instrument schedStat;
  370.     ReturnStatus    status;
  371.     int            i;
  372.  
  373.     status = Sys_Stats(SYS_SCHED_STATS, 0, &schedStat);
  374.     if (status != SUCCESS) {
  375.     return;
  376.     }
  377.     printf("Sched Statistics\n");
  378.     for (i = 0; i < numProcessors; i++) {
  379.     printf("Processor %d\n", i);
  380.     printf("numContextSwitches = %d\n", 
  381.             schedStat.processor[i].numContextSwitches);
  382.     printf("numFullSwitches    = %d\n", schedStat.processor[i].numFullCS);
  383.     printf("numInvoluntary     = %d\n", 
  384.             schedStat.processor[i].numInvoluntarySwitches);
  385. #ifdef notdef
  386.     printf("onDeckSelf       = %d\n",
  387.             schedStat.processor[i].onDeckSelf);
  388.     printf("onDeckOther       = %d\n",
  389.             schedStat.processor[i].onDeckOther);
  390. #endif notdef
  391.     printf("Idle Time          = %d.%06d seconds\n",
  392.            schedStat.processor[i].idleTime.seconds,
  393.            schedStat.processor[i].idleTime.microseconds);
  394.         printf("Idle ticks = %d * 2^32 + %d.\n", 
  395.             schedStat.processor[i].idleTicksOverflow,
  396.             schedStat.processor[i].idleTicksLow);
  397.     printf("Idle ticks/sec = %d.\n", 
  398.             schedStat.processor[i].idleTicksPerSecond);
  399.     }
  400. }
  401.  
  402. @
  403.  
  404.  
  405. 1.7
  406. log
  407. @prints tick overflows
  408. @
  409. text
  410. @d18 1
  411. a18 1
  412. static char rcsid[] = "$Header: /a/newcmds/sysstat/RCS/sysstat.c,v 1.6 89/10/18 22:40:23 jhh Exp Locker: jhh $ SPRITE (Berkeley)";
  413. d22 1
  414. d25 1
  415. d43 3
  416. d50 1
  417. d53 1
  418. a53 3
  419.     {OPT_TRUE, "v", (Address)&printVersion,
  420.      "Print compilation timestamp for the kernel (DEFAULT)."},
  421.     {OPT_TRUE, "c", (Address)&countCalls,
  422. d55 3
  423. d60 4
  424. a63 1
  425.     {OPT_TRUE, "l", (Address)&doSyncStat, "Print lock (Sync) statistics"},
  426. a97 1
  427.     int migStatus;
  428. d100 1
  429. d134 1
  430. a134 1
  431.     status = PrintNumCalls();
  432. d136 5
  433. d145 17
  434. d164 2
  435. a165 2
  436.     printf("Sys_GetMachineInfo returned 0x%x.\n", status);
  437.     exit(status);
  438. d175 1
  439. a175 1
  440.     exit(status);
  441. d196 3
  442. a198 3
  443.  
  444. int
  445. PrintNumCalls()
  446. d201 1
  447. d206 4
  448. a209 2
  449.     register int *numCalls;
  450.     int numAlloc;
  451. d212 3
  452. a214 1
  453.      * Get a copy of the array of counters.
  454. d216 5
  455. d222 7
  456. a228 3
  457.     numAlloc = sysCallArraySize / sizeof(SysCallInfo);
  458.     buffer = malloc((unsigned) (numAlloc * sizeof(int)));
  459.     status = Sys_Stats(SYS_SYS_CALL_STATS, numAlloc, buffer);
  460. d230 3
  461. a232 1
  462.     Stat_PrintMsg(status, "Error from Test_Stats");
  463. d235 5
  464. d241 1
  465. d244 9
  466. a252 4
  467.     (void) printf("%d\t%-30s", numCalls[i], sysCallArray[i].name);
  468.     if (sysCallArray[i].local) {
  469.         numLocal += numCalls[i];
  470.         (void) printf("local\n");
  471. d254 16
  472. a269 2
  473.         numForeign += numCalls[i];
  474.         (void) printf("remote\n");
  475. d272 7
  476. a278 5
  477.     (void) printf("\n\nTotal number of calls: %d local, %d remote.\n",
  478.        numLocal, numForeign);
  479.     (void) printf("%d/%d = %6.2f%% remote.\n",
  480.        numForeign, numForeign + numLocal, 
  481.        ((double) numForeign) / (numForeign + numLocal) * 100.);
  482. a309 1
  483.     Time idleTime;
  484. @
  485.  
  486.  
  487. 1.6
  488. log
  489. @checking in old change
  490. @
  491. text
  492. @d18 1
  493. a18 1
  494. static char rcsid[] = "$Header: /a/newcmds/sysstat/RCS/sysstat.c,v 1.5 89/08/30 09:19:03 brent Exp Locker: jhh $ SPRITE (Berkeley)";
  495. d260 5
  496. @
  497.  
  498.  
  499. 1.5
  500. log
  501. @Changed the format of kernel version string that is printed out
  502. to
  503. hostname          SPRITE VERSION ...
  504. @
  505. text
  506. @d18 1
  507. a18 1
  508. static char rcsid[] = "$Header: /a/newcmds/sysstat/RCS/sysstat.c,v 1.4 89/08/29 15:58:03 jhh Exp Locker: brent $ SPRITE (Berkeley)";
  509. a19 2
  510.  
  511. #include "sched.h"
  512. @
  513.  
  514.  
  515. 1.4
  516. log
  517. @Updated to new structure definitions
  518. @
  519. text
  520. @d18 1
  521. a18 1
  522. static char rcsid[] = "$Header: /a/newcmds/sysstat/RCS/sysstat.c,v 1.3 89/08/03 16:05:30 brent Exp $ SPRITE (Berkeley)";
  523. d29 1
  524. d102 19
  525. a120 1
  526.         (void) printf("Kernel version: %s\n", version);
  527. d253 1
  528. d258 1
  529. @
  530.  
  531.  
  532. 1.3
  533. log
  534. @Added Sched and Lock statistics.
  535. @
  536. text
  537. @d18 1
  538. a18 1
  539. static char rcsid[] = "$Header: /a/newcmds/sysstat/RCS/sysstat.c,v 1.2 88/12/22 11:07:44 douglis Exp Locker: brent $ SPRITE (Berkeley)";
  540. d21 2
  541. d33 1
  542. d90 2
  543. d113 6
  544. a118 1
  545.  
  546. d120 1
  547. a120 1
  548.     PrintSyncStats();
  549. d123 1
  550. a123 1
  551.     PrintSchedStats();
  552. d190 2
  553. a191 1
  554. PrintSyncStats()
  555. d193 1
  556. a193 1
  557.     Sync_Instrument    syncStat;
  558. d195 1
  559. d197 1
  560. a197 1
  561.     status = Sys_Stats(SYS_SYNC_STATS, 0, &syncStat);
  562. d202 10
  563. a211 6
  564.     printf("numWakeups = %d ", syncStat.numWakeups);
  565.     printf("numWakeupCalls = %d ", syncStat.numWakeupCalls);
  566.     printf("numSpuriousWakeups = %d ", syncStat.numSpuriousWakeups);
  567.     printf("numLocks = %d ", syncStat.numLocks);
  568.     printf("numUnlocks = %d ", syncStat.numUnlocks);
  569.     printf("\n");
  570. d214 2
  571. a215 1
  572. PrintSchedStats()
  573. d220 1
  574. d227 15
  575. a241 8
  576.     printf("numContextSwitches = %d\n", 
  577.         schedStat.processor[0].numContextSwitches);
  578.     printf("numFullSwitches    = %d\n", schedStat.processor[0].numFullCS);
  579.     printf("numInvoluntary     = %d\n", 
  580.         schedStat.processor[0].numInvoluntarySwitches);
  581.     printf("Idle Time          = %d.%06d seconds\n",
  582.            schedStat.processor[0].idleTime.seconds,
  583.            schedStat.processor[0].idleTime.microseconds);
  584. @
  585.  
  586.  
  587. 1.2
  588. log
  589. @moved a bunch of stuff out of this, into migcmd.
  590. @
  591. text
  592. @d18 1
  593. a18 1
  594. static char rcsid[] = "$Header: /a/newcmds/sysstat/RCS/sysstat.c,v 1.1 88/10/31 13:57:46 douglis Exp Locker: douglis $ SPRITE (Berkeley)";
  595. d29 2
  596. d41 2
  597. d51 2
  598. d109 7
  599. d179 40
  600. @
  601.  
  602.  
  603. 1.1
  604. log
  605. @Initial revision
  606. @
  607. text
  608. @d4 2
  609. a5 1
  610.  *    Statistics generation for system calls and process migration.
  611. d18 1
  612. a18 1
  613. static char rcsid[] = "$Header: sysStat.c,v 1.5 88/09/26 17:26:53 douglis Exp $ SPRITE (Berkeley)";
  614. d25 1
  615. a28 1
  616. #include <kernel/procMigrate.h>
  617. d30 2
  618. a36 6
  619. int allowMigration = 0;
  620. int refuseMigration = 0;
  621. int getMigStatus = 0;
  622. int doMigration = 0;
  623. int startTrace = 0;
  624. int stopTrace = 0;
  625. a38 2
  626. int debugLevel = -1;
  627. int numRecords = 200;
  628. d41 2
  629. a44 12
  630.     {OPT_INT, "d", (Address)&debugLevel,
  631.      "Level to set proc_MigDebugLevel."},
  632.     {OPT_TRUE, "S", (Address)&getMigStatus,
  633.      "Print whether process migration is allowed."},
  634.     {OPT_TRUE, "a", (Address)&allowMigration,
  635.      "Allow future migrations to this machine (must be root)."},
  636.     {OPT_TRUE, "r", (Address)&refuseMigration,
  637.      "Disallow future migrations to this machine (must be root)."},
  638.     {OPT_TRUE, "m", (Address)&doMigration,
  639.      "Print process migration statistics."},
  640.     {OPT_INT, "n", (Address)&numRecords,
  641.      "Number of process migration records to print."},
  642. a46 6
  643.     {OPT_TRUE, "t", (Address)&startTrace,
  644.      "Enable tracing of process migration."},
  645.     {OPT_TRUE, "T", (Address)&stopTrace,
  646.      "Disable tracing of process migration."},
  647.     {OPT_TRUE, "V", (Address)&printVersion,
  648.      "Print compilation timestamp for the kernel."},
  649. a47 1
  650. int numOptions = sizeof(optionArray) / sizeof(Option);
  651. a55 106
  652. /*
  653.  * List of system calls to print out, corresponding to call number.
  654.  * Whether or not they're local should be taken from some other
  655.  * file in the kernel rather than repeated here....
  656.  */
  657.  
  658. typedef struct {
  659.     char *name;
  660.     int local;
  661. } SysCallInfo;
  662.  
  663. static SysCallInfo callArray[] = {
  664.     "Proc_Fork",        0,
  665.     "Proc_Exec",                0,
  666.     "Proc_Exit",                0,
  667.     "Sync_WaitTime",            1,
  668.     "Test_PrintOut",            1,    
  669.     "Test_GetLine",             1,
  670.     "Test_GetChar",             1,
  671.     "Fs_OpenStub",              1,
  672.     "Fs_ReadStub",              1,
  673.     "Fs_WriteStub",             1,
  674.     "Fs_UserClose",             1,
  675.     "Fs_RemoveStub",            1,
  676.     "Fs_RemoveDirStub",         1,
  677.     "Fs_MakeDirStub",           1,
  678.     "Fs_ChangeDirStub",         1,
  679.     "Proc_Wait",                0,
  680.     "Proc_Detach",              0,
  681.     "Proc_GetIDs",              0,
  682.     "Proc_SetIDs",              0,
  683.     "Proc_GetGroupIDs",         0,
  684.     "Proc_SetGroupIDs",         0,
  685.     "Proc_GetFamilyID",         0,
  686.     "Proc_SetFamilyID",         0,
  687.     "Test_RpcStub",             1,
  688.     "Test_StatsStub",           1,
  689.     "Vm_CreateVA",              1,
  690.     "Vm_DestroyVA",             1,
  691.     "Sig_UserSend",             0,
  692.     "Sig_Pause",                1,
  693.     "Sig_SetHoldMask",          1,
  694.     "Sig_SetAction",            1,
  695.     "Prof_Start",               1,
  696.     "Prof_End",                 1,
  697.     "Prof_DumpStub",            0,
  698.     "Vm_Cmd",                   0,
  699.     "Sys_GetTimeOfDay",         0,
  700.     "Sys_SetTimeOfDay",         0,
  701.     "Sys_DoNothing",            1,
  702.     "Proc_GetPCBInfo",          0,
  703.     "Vm_GetSegInfo",            1,
  704.     "Proc_GetResUsage",         0,
  705.     "Proc_GetPriority",         0,
  706.     "Proc_SetPriority",         0,
  707.     "Proc_Debug",               0,
  708.     "Proc_Profile",             0,
  709.     "Fs_TruncateStub",          1,
  710.     "Fs_TruncateIDStub",        1,
  711.     "Fs_GetNewIDStub",          1,
  712.     "Fs_GetAttributesStub",     1,
  713.     "Fs_GetAttributesIDStub",   1,
  714.     "Fs_SetAttributesStub",     1,
  715.     "Fs_SetAttributesIDStub",   1,
  716.     "Fs_SetDefPermStub",        1,
  717.     "Fs_IOControlStub",         1,
  718.     "Dev_VidEnable",            0,
  719.     "Proc_SetEnviron",          0,
  720.     "Proc_UnsetEnviron",        0,
  721.     "Proc_GetEnvironVar",       0,
  722.     "Proc_GetEnvironRange",     0,
  723.     "Proc_InstallEnviron",      0,
  724.     "Proc_CopyEnviron",         0,
  725.     "Sync_SlowLockStub",        1,
  726.     "Sync_SlowWaitStub",        1,
  727.     "Sync_SlowBroadcastStub",   1,
  728.     "Vm_PageSize",              1,
  729.     "Fs_HardLinkStub",          1,
  730.     "Fs_RenameStub",            1,
  731.     "Fs_SymLinkStub",           1,
  732.     "Fs_ReadLinkStub",          1,
  733.     "Fs_CreatePipeStub",        1,
  734.     "Vm_MapKernelIntoUser",     0,
  735.     "Fs_AttachDiskStub",        0,
  736.     "Fs_SelectStub",            1,
  737.     "Sys_Shutdown",             0,
  738.     "Proc_Migrate",             0,
  739.     "Fs_MakeDeviceStub",        1,
  740.     "Fs_CommandStub",           0,
  741.     "Fs_LockStub",              1,
  742.     "Sys_GetMachineInfo",     1,
  743.     "Net_InstallRoute",     0,
  744.     "Fs_ReadVector",         1,
  745.     "Fs_WriteVector",         1,
  746.     "Fs_CheckAccess",         1,
  747.     "Proc_GetIntervalTimer",     1,
  748.     "Proc_SetIntervalTimer",     1,
  749.     "Fs_FileWriteBackStub",    1,
  750.     "Proc_ExecEnv",        1,
  751. };
  752.  
  753. /*
  754.  * Forward and external references.
  755.  */
  756. extern char *malloc();
  757.  
  758. d82 1
  759. a82 1
  760.     (void) Opt_Parse(argc, argv, optionArray, numOptions,
  761. d84 3
  762. a94 66
  763.     if (debugLevel != -1) {
  764.     status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_SET_DEBUG,
  765.                (Address) &debugLevel);
  766.     if (status != SUCCESS) {
  767.         Stat_PrintMsg(status, "Sys_Stats (set debug level)");
  768.         exit(status);
  769.     }
  770.     }
  771.  
  772.     if (allowMigration || refuseMigration || getMigStatus) {
  773.     status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_GET_STATUS,
  774.                (Address) &migStatus);
  775.     if (status != SUCCESS) {
  776.         Stat_PrintMsg(status, "Sys_Stats (getting migration status)");
  777.         exit(status);
  778.     }
  779.  
  780.     if (allowMigration) {
  781.         status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_ALLOW,
  782.                    (Address) NULL);
  783.         if (status != SUCCESS) {
  784.         Stat_PrintMsg(status, "Sys_Stats (allow migration)");
  785.         exit(status);
  786.         }
  787.         (void) printf("Migration is currently allowed, previously %s.\n",
  788.              migStatus ? "refused" : "allowed");
  789.     } else if (refuseMigration) {
  790.         status = Sys_Stats(SYS_PROC_MIGRATION, SYS_PROC_MIG_REFUSE,
  791.                    (Address) NULL);
  792.         if (status != SUCCESS) {
  793.         Stat_PrintMsg(status, "Sys_Stats (refuse migration)");
  794.         exit(status);
  795.         }
  796.         (void) printf("Migration is currently refused, previously %s.\n",
  797.              migStatus ? "refused" : "allowed");
  798.     } else {
  799.         (void) printf("Migration is currently %s.\n",
  800.              migStatus ? "refused" : "allowed");
  801.     }
  802.     }
  803.     if (startTrace) {
  804.     status = Sys_Stats(SYS_PROC_TRACE_STATS, SYS_PROC_TRACING_ON,
  805.             (Address) NULL);
  806.     if (status != SUCCESS) {
  807.         (void) fprintf(stderr, "Error %x returned from Test_Stats.\n",
  808.                status);
  809.         Stat_PrintMsg(status, "");
  810.         exit(status);
  811.     }
  812.     }
  813.  
  814.     if (stopTrace) {
  815.     status = Sys_Stats(SYS_PROC_TRACE_STATS, SYS_PROC_TRACING_OFF,
  816.             (Address) NULL);
  817.     if (status != SUCCESS) {
  818.         (void) fprintf(stderr, "Error %x returned from Test_Stats.\n",
  819.                status);
  820.         Stat_PrintMsg(status, "");
  821.         exit(status);
  822.     }
  823.     }
  824.  
  825.     if (doMigration) {
  826.     status = PrintMigration();
  827.     }
  828.  
  829. a109 122
  830.  * PrintMigration --
  831.  *
  832.  *    Print the most recent process migration trace records.
  833.  *
  834.  * Results:
  835.  *    The return status from Test_Stats is returned.
  836.  *
  837.  * Side effects:
  838.  *    Trace records are written to stdout.
  839.  *
  840.  *----------------------------------------------------------------------
  841.  */
  842.  
  843.  
  844. int
  845. PrintMigration()
  846. {
  847.     int index;        /* index of current table entry */
  848.     Time baseTime, deltaTime, startTime;    /* Times for print out */
  849.     Address buffer;    /* Buffer for trace records */
  850.     int numRecs;        /* number of records actually copied */
  851.     Trace_Record *traceArray;
  852.     Proc_TraceRecord *procTraceArray;
  853.     register Trace_Record *tracePtr;
  854.     register Proc_TraceRecord *procTracePtr;
  855.     int status;
  856.     static char *flagsArray[] = {"RE", "RS", "HE", "HS", "  "};
  857.     static char *eventArray[] = {"start", "end", "xfer", "call", "migtrap"};
  858.     static char *commandArray[] = {"proc", "vm", "files", "stream", "user",
  859.                  "resume"};
  860.     /*
  861.      * Get a copy of the trace table.
  862.      */
  863.  
  864.     buffer = malloc((unsigned) (sizeof(int) + numRecords *
  865.                 (sizeof(Trace_Record) +
  866.                  sizeof(Proc_TraceRecord))));
  867.     status = Sys_Stats(SYS_PROC_TRACE_STATS, numRecords, buffer);
  868.     if (status != SUCCESS) {
  869.     (void) fprintf(stderr, "Error from Test_Stats.\n");
  870.     Stat_PrintMsg(status, "");
  871.     return(status);
  872.     }
  873.  
  874.     numRecs = * ((int *) buffer);
  875.     buffer += sizeof(int);
  876.     (void) fprintf(stderr, "Number of records is %d.\n", numRecs);
  877.     (void) fflush(stderr);
  878.     if (numRecs == 0) {
  879.     return(0);
  880.     }
  881.  
  882.     traceArray = (Trace_Record *) buffer;
  883.     procTraceArray = (Proc_TraceRecord *) (buffer + numRecs *
  884.                      sizeof(Trace_Record));
  885.  
  886.  
  887.     (void) printf("\n");
  888. #define PRINT_MIGHEADER() \
  889.     (void) printf("%10s %10s %10s %2s %10s %24s %7s\n", \
  890.     "Time", "Delta", "ProcessID", "HR", "Event", "Call", "Sta")
  891.     PRINT_MIGHEADER();
  892.  
  893.     baseTime = traceArray[0].time;
  894.     startTime = traceArray[0].time;
  895.  
  896.     for (index = 0; index < numRecs; index++) {
  897.     tracePtr = &traceArray[index];
  898.     procTracePtr = &procTraceArray[index];
  899.  
  900.     Time_Subtract(tracePtr->time, startTime, &deltaTime);
  901.     (void) printf(" %3d.%06d",
  902.                deltaTime.seconds,
  903.                deltaTime.microseconds);
  904.     Time_Subtract(tracePtr->time, baseTime, &deltaTime);
  905.     (void) printf(" %3d.%06d",
  906.                deltaTime.seconds,
  907.                deltaTime.microseconds);
  908.     baseTime = tracePtr->time;
  909.  
  910.     if (tracePtr->flags & TRACE_DATA_INVALID) {
  911.         procTracePtr->flags = 4;
  912.         procTracePtr->processID = (Proc_PID) NULL;
  913.     }
  914.     if (((unsigned) procTracePtr->flags) > 3 ||
  915.         ((unsigned) tracePtr->event)  >= PROC_NUM_EVENTS) {
  916.         (void) fprintf(stderr,
  917.                    "Entry %d: invalid flags (%d) or event (%d).\n",
  918.                    index, procTracePtr->flags, tracePtr->event);
  919.         return(-1);
  920.         }
  921.  
  922.     (void) printf("%10x %3s %10s", procTracePtr->processID,
  923.               flagsArray[procTracePtr->flags],
  924.               eventArray[tracePtr->event]);
  925.  
  926.     if (tracePtr->event == PROC_MIGTRACE_TRANSFER) {
  927.         (void) printf(" %-10s",
  928.              commandArray[(int) procTracePtr->info.command.type]);
  929.         if (procTracePtr->info.command.data != (ClientData) NIL) {
  930.         (void) printf(" %20d",
  931.                    procTracePtr->info.command.data);
  932.         }
  933.     } else if (tracePtr->event == PROC_MIGTRACE_CALL) {
  934.         (void) printf(" %24s",
  935.              callArray[(int) procTracePtr->info.call.callNumber].name);
  936.         if (!(procTracePtr->flags & PROC_MIGTRACE_START)) {
  937.         (void) printf(" %10x",
  938.                    procTracePtr->info.call.status);
  939.         }
  940.     }
  941.  
  942.     (void) printf("\n");
  943.     }
  944.     PRINT_MIGHEADER();
  945.     return(0);
  946. }
  947.  
  948.  
  949. /*
  950.  *----------------------------------------------------------------------
  951.  *
  952. d140 1
  953. a140 1
  954.     numAlloc = sizeof(callArray) / sizeof(SysCallInfo);
  955. d150 2
  956. a151 2
  957.     (void) printf("%d\t%-30s", numCalls[i], callArray[i].name);
  958.     if (callArray[i].local) {
  959. d163 1
  960. a163 1
  961.        ((double) numForeign) / (numForeign + numLocal));
  962. @
  963.